/**
 * Created by Administrator on 2017/3/9 0009.
 */
//定义一个全局script的标记数组，用来标记是否某个script已经下载到本地
var scriptsArray = new Array();
var currentFireCount = 0;
var material = null;
var secondCanvas = document.getElementById("2dCanvas");
var sectionContent = document.getElementById("sectionContent");
var maxCapacity = 5;
var countCapacity = 0;

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD module
        define(factory);
    } else {
        // Browser global
        root.Lighting = factory();
    }
}(this, function () {
    if (typeof Date.now !== 'function') Date.now = function () {
        return new Date().getTime();
    };
    var Lighting = {
        create: function (options) {
            return (function () {
                //确保需要的参数都已经传进来
                // if (!options || !options.ratio || !options.renderCanvasId || !options.modelPath || !options.modelName) {
                //     throw 'Missing paramSSSSS!';
                // }
                // 常量
                var CONSTANT1 = 'top',
                    CONSTANT2 = 'right',
                    CONSTANT3 = 'bottom',
                    CONSTANT4 = 'left';
                //默认的参数
                var config = {
                    /*
                     animationType  存放导入模型的动画类型
                     isShowAxis 是否显示坐标系
                     isShowOriginMesh   是否显示原（导入的）模型
                     currentKeyFrameSectionData 存放当前帧数下的数据信息
                     allSectionData 存放所以的切片信息
                     importedMesh   存放导入的所以模型
                     modelStartX    模型的起始X
                     modelStartY    模型的起始X
                     modelStartZ    模型的起始Z
                     modelWidth     模型的宽度
                     minX           模型最小的X坐标
                     minY           模型最小的Y坐标
                     minZ           模型最小的Z坐标
                     maxX           模型最大的X坐标
                     maxY           模型最大的Y坐标
                     maxZ           模型最大的Z坐标
                     screenLength   屏幕的长
                     screenHeight   屏幕的高
                     screenWidth    屏幕的宽
                     a/b/c/d        平面方程的四个参数
                     */
                    animationType: [],
                    isShowAxis: false,
                    isShowOriginMesh: false,
                    currentKeyFrameSectionData: [],
                    allSectionData: [],
                    importedMesh: [],
                    modelStartX: null,
                    modelStartY: null,
                    modelStartZ: null,
                    modelWidth: null,
                    minX: null,
                    minY: null,
                    minZ: null,
                    maxX: null,
                    maxY: null,
                    maxZ: null,
                    screenLength: null,
                    screenHeight: null,
                    screenWidth: null,
                    meshLength: null,
                    meshHeight: null,
                    meshWidth: null,
                    a: 0,
                    b: 0,
                    c: 0,
                    d: 0,
                };
                //执行函数
                configure(options);
                /**
                 * 根据USER传入的参数初始化Lighting,
                 * 随着参数改变可能会调用多次.
                 */
                function configure(o) {
                    /*
                    参数扩展:将传入的参数扩展到Lighting
                     */
                    Lighting.extend(config, o);
                    /*
                     扩展Ajax加载js文件的插件：E.g
                     $.cachedScript('js/voxelize.js').done(function () {
                         console.log(scriptsArray);//回调函数，上面voxelize文件加载成功后才执行的方法
                     });
                     */
                    Lighting.extendJqueryLoadJsFunc();
                    Lighting.createScene(config);
                }

                /// API: ///////////////////////////////////
                return {
                    configure: configure,
                };
            })();
        },
        initWebSocketConnection:function (wsUri) {
            websocket = new WebSocket(wsUri);
            websocket.onopen = function(evt) {
                console.log("Connected!");
            };
            websocket.onclose = function(evt) {
                console.log("Disconnected!");
                console.log(evt)
            };
            websocket.onmessage = function(evt) {
                var tempFireworkType = "fireworkVersion"+evt.data;
                if(tempFireworkType == "fireworkVersion400"){
                    return true;
                }
                var tempName = "demoJs/"+tempFireworkType+".js";
                if(tempFireworkType == "fireworkVersion1"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion1(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion2"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion2(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion3"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion3(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion4"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion4(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion5"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion5(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion6"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion6(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion7"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion7(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion8"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion8(scene);
                    });
                }else if(tempFireworkType == "fireworkVersion9"){
                    $.cachedScript(tempName).done(function () {
                        fireworkVersion9(scene);
                    });
                }

                else{
                    console.log("fireworkVersion"+evt.data+"not Defined!!!")
                }
            };
            websocket.onerror = function(evt) {
                console.log("Error:"+evt.data);
            };
        },
        sendMessageToServer:function (message) {
            websocket.send(message);
        },
        initSectionArray: function (config) {
            var sectionData = [];//当前"面"的切片数据
            var tempArray = [];
            for (var i = 0; i < Math.ceil(config.pickWidth / config.ratio); i++) {
                for (var j = 0; j < Math.ceil(config.pickHeight / config.ratio); j++) {
                    for (var k = 0; k < Math.ceil(config.pickLength / config.ratio); k++) {
                        tempArray.push(0);
                    }
                    sectionData.push(tempArray);
                    tempArray = [];
                }
                config.allSectionData.push(sectionData);
                config.currentKeyFrameSectionData.push(sectionData);
                sectionData = [];
            }
        },
        createScene: function (config) {
            (config.dragElementId)?DRAG.drag(config.dragElementId): true;
            var canvas = document.getElementById(config.renderCanvasId);
            var engine = new BABYLON.Engine(canvas, null, false);
            var createSceneFunc = function () {
                var scene = new BABYLON.Scene(engine);
                var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", -1, 1, 100, new BABYLON.Vector3(0, 0, 0), scene);
                var light1 = new BABYLON.HemisphericLight("HemisphericLight1", new BABYLON.Vector3(60, 60, 60), scene);
                var light2 = new BABYLON.HemisphericLight("HemisphericLight2", new BABYLON.Vector3(-60, -60, -60), scene);
                light1.specular = new BABYLON.Color3(0, 0, 0);
                light2.specular = new BABYLON.Color3(0, 0, 0);
                camera.attachControl(canvas, true);
                camera.setTarget(new BABYLON.Vector3(5,5,5));
                var materialSphere1 = new BABYLON.StandardMaterial("texture1", scene);
                materialSphere1.diffuseColor = new BABYLON.Color3(0.0, 1, 0.7);
                materialSphere1.backFaceCulling = false;
                materialSphere1.wireframe = config.isShowMeshWireframe || false;
                (config.isShowAxis) ? Lighting.showAxis(100,scene): true;
                if(config.modelType == "bone"){
                    Lighting.doBoneAnimation(config,scene);
                }else if(config.modelType == "transform"){
                    Lighting.doTransformAnimation(config,scene);
                }else if(config.modelType == "static"){
                    Lighting.doStaticFunc(config,scene)
                }else if(config.modelType == "effect"){
                    Lighting.doEffectAnimation(config,scene);
                }
                return scene;
            };
            scene = createSceneFunc();
            engine.runRenderLoop(function () {
                scene.render();
            });
            window.addEventListener('resize', function () {
                engine.resize();
            });
        },
        doEffectAnimation:function (config,scene) {
            /*
             加载控制函数
             */
            $.cachedScript('./js/controller.js');
        },
        doBoneAnimation:function (config,scene) {
            BABYLON.SceneLoader.ImportMesh("", config.modelPath, config.modelName, scene, function (newMeshes, particleSystems, skeletons) {
                var mesh = newMeshes[0];
                mesh.scaling = new BABYLON.Vector3(.4,.4,.4);
                // mesh.bakeCurrentTransformIntoVertices()
                var tmpPos = new BABYLON.Vector3.Zero();
                // scene.beginAnimation(skeletons[0], 0, 100, true, 1.0);
                // scene.registerBeforeRender(function () {
                //     newMeshes[0].getChildren()[0].computeWorldMatrix(true);
                //     for(var j = 0;j<newMeshes[0].getChildren().length;j++){
                //         var positions = newMeshes[0].getChildren()[j].getVerticesData(BABYLON.VertexBuffer.PositionKind);
                //         var indices = newMeshes[0].getChildren()[j].getIndices();
                //
                //         // console.log(newMeshes[0].getChildren()[0].getWorldMatrix().m)
                //         for(var i=0;i<indices.length;i+=3){
                //             var tempArray = [];
                //             for (var k = 0; k < 3; k++) {
                //                 tmpPos.x = positions[indices[i+k]*3];
                //                 tmpPos.y = positions[indices[i+k]*3+1];
                //                 tmpPos.z = positions[indices[i+k]*3+2];
                //                 tempArray.push(BABYLON.Vector3.TransformCoordinates(tmpPos,newMeshes[0].getChildren()[j].getWorldMatrix()))
                //             }
                //             Lighting.createPlan(tempArray, scene, config)
                //         }
                //     }
                // })
            })
        },
        doTransformAnimation:function (config,scene) {
            BABYLON.SceneLoader.ImportMesh("", config.modelPath, config.modelName, scene, function (newMeshes) {
                //模型和动画类型数组相对应
                if (newMeshes[0].animations.length == 0) {
                    for (var i = 0; i < newMeshes.length; i++) {
                        config.importedMesh.push(newMeshes[i]);
                    }
                    Lighting.doStaticFunc(config, scene);
                } else {
                    for (var i = 0; i < newMeshes.length; i++) {
                        config.importedMesh.push(newMeshes[i]);
                        config.animationType.push(config.importedMesh[i].animations[0].targetProperty);
                    }
                    for (var t = 0; t < config.animationType.length; t++) {
                        switch (config.animationType[t]) {
                            case "position":
                                Lighting.doPositionAnimationFunc(config, scene);
                                break;
                            case "rotationQuaternion":
                                Lighting.doRotateAnimationFunc(config, scene);
                                break;
                            case "scaling":
                                Lighting.doScalingAnimationFunc(config, scene);
                                break;
                            default:
                                console.log("Type : " + config.animationType + " not handle yet!")
                        }
                    }
                }


            });
        },
        doStaticFunc: function (config, scene) {
            Lighting.initSectionArray(config);
            var positions = config.importedMesh[0].getVerticesData(BABYLON.VertexBuffer.PositionKind);
            var tmpPos = new BABYLON.Vector3.Zero();
            var isFirst = false;
            scene.registerBeforeRender(function () {
                if (!isFirst) {
                    secondCanvas.width = secondCanvas.width;
                    for (var i = 0; i < positions.length; i += 9) {
                        //存放当前三角面的3个顶点数据i{x:,,,y:,,,z;,,,}
                        var tempArray = [];
                        for (var j = 0; j < 3; j++) {
                            tmpPos.x = positions[(j * 3) + i];
                            tmpPos.y = positions[(j * 3) + i + 1];
                            tmpPos.z = positions[(j * 3) + i + 2];
                            tempArray.push(BABYLON.Vector3.TransformCoordinates(tmpPos, config.importedMesh[0].getWorldMatrix()))
                        }
                        ;
                        Lighting.createPlan(tempArray, scene, config)
                    }
                    isFirst = !isFirst;
                }
            });
            console.log("doStaticAnimationFunc Done!!!!!!!!!!!")
        },
        doRotateAnimationFunc: function (config, scene) {
            Lighting.initSectionArray(config);
            var positions = config.importedMesh[0].getVerticesData(BABYLON.VertexBuffer.PositionKind);
            var tmpPos = new BABYLON.Vector3.Zero();
            scene.registerBeforeRender(function () {
                secondCanvas.width = secondCanvas.width;
                // console.log(positions.length)
                for (var i = 0; i < positions.length; i += 9) {
                    //存放当前三角面的3个顶点数据i{x:,,,y:,,,z;,,,}
                    var tempArray = [];
                    for (var j = 0; j < 3; j++) {
                        tmpPos.x = positions[(j * 3) + i];
                        tmpPos.y = positions[(j * 3) + i + 1];
                        tmpPos.z = positions[(j * 3) + i + 2];
                        tempArray.push(BABYLON.Vector3.TransformCoordinates(tmpPos, config.importedMesh[0].getWorldMatrix()))
                    }
                    ;
                    // console.log(tempArray.toString())
                    Lighting.createPlan(tempArray, scene, config)
                }
                //清空所以添加的模型
            });
            console.log("doRotateAnimationFunc Done!!!!!!!!!!!")
        },
        doScalingAnimationFunc: function (config, scene) {
            Lighting.initSectionArray(config);
            var positions = config.importedMesh[0].getVerticesData(BABYLON.VertexBuffer.PositionKind);
            var tmpPos = new BABYLON.Vector3.Zero();
            scene.registerBeforeRender(function () {
                secondCanvas.width = secondCanvas.width;
                // console.log(positions.length)
                for (var i = 0; i < positions.length; i += 9) {
                    //存放当前三角面的3个顶点数据i{x:,,,y:,,,z;,,,}
                    var tempArray = [];
                    for (var j = 0; j < 3; j++) {
                        tmpPos.x = positions[(j * 3) + i];
                        tmpPos.y = positions[(j * 3) + i + 1];
                        tmpPos.z = positions[(j * 3) + i + 2];
                        tempArray.push(BABYLON.Vector3.TransformCoordinates(tmpPos, config.importedMesh[0].getWorldMatrix()))
                    }
                    ;
                    // console.log(tempArray.toString())
                    Lighting.createPlan(tempArray, scene, config)
                }
                //清空所以添加的模型
            });
            console.log("doScalingAnimationFunc Done!!!!!!!!!!!")
        },
        doPositionAnimationFunc: function (config, scene) {
            Lighting.initSectionArray(config);
            var positions = config.importedMesh[0].getVerticesData(BABYLON.VertexBuffer.PositionKind);
            // var ss = new BABYLON.StandardMaterial("asd",scene);
            // ss.wireframe = true;
            // config.importedMesh[0].material = ss;
            var tmpPos = new BABYLON.Vector3.Zero();
            var isFirst = false;
            var countPosition = 0;
            scene.registerBeforeRender(function () {
                if (!isFirst) {
                    secondCanvas.width = secondCanvas.width;
                    // for (var i = 0; i < positions.length; i += 9) {
                    for (var i = 0; i < positions.length; i += 9) {
                        //存放当前三角面的3个顶点数据i{x:,,,y:,,,z;,,,}
                        var tempArray = [];
                        for (var j = 0; j < 3; j++) {
                            tmpPos.x = positions[(j * 3) + i];
                            tmpPos.y = positions[(j * 3) + i + 1];
                            tmpPos.z = positions[(j * 3) + i + 2];
                            tempArray.push(BABYLON.Vector3.TransformCoordinates(tmpPos, config.importedMesh[0].getWorldMatrix()))
                        };
                        Lighting.createPlan(tempArray, scene, config)
                    }
                    isFirst = !isFirst;
                }
                //清空所以添加的模型
            });
            console.log("I'm doPositionAnimationFunc")
        },
        createPlan: function (vertex3Array, scene, config) {
            //计算当前面的平面方程
            Lighting.CalculatePlaneEquation(vertex3Array, config);
            //计算当前三角形的minX/minY/minZ/maxX/maxY/maxZ
            var minX, minY, minZ, maxX, maxY, maxZ;
            for (var i = 0; i < vertex3Array.length; i++) {
                if (i == 0) {
                    minX = maxX = vertex3Array[i].x;
                    minY = maxY = vertex3Array[i].y;
                    minZ = maxZ = vertex3Array[i].z;
                } else {
                    if (vertex3Array[i].x <= minX) {
                        minX = vertex3Array[i].x;
                    }
                    else {
                        maxX = vertex3Array[i].x;
                    }
                    if (vertex3Array[i].y <= minY) {
                        minY = vertex3Array[i].y;
                    }
                    else {
                        maxY = vertex3Array[i].y;
                    }
                    if (vertex3Array[i].z <= minZ) {
                        minZ = vertex3Array[i].z;
                    }
                    else {
                        maxZ = vertex3Array[i].z;
                    }
                }
            }
            //计算当前面minX和maxX之间的距离是否大于分辨率、小于分辨率、等于分辨率。
            /*
             offset* :当前三角形的在分辨率下的起始坐标。。。
             countX*:当前面所占的分辨率。。。
             */
            // var offsetX = Math.floor((minX - config.pickStartX)/config.ratio);
            // console.log(parseInt((minX - config.pickStartX)/config.ratio))
            // console.log((minX - config.pickStartX)%config.ratio)
            // console.log(parseInt((minX - config.pickStartX)/config.ratio)+(minX - config.pickStartX)%config.ratio == (minX - config.pickStartX)/config.ratio)
            // console.log(parseInt(((maxX-minX)/config.ratio)))
            // console.log((maxX-minX)%config.ratio)
            var countX = 0;
            var countY = 0;
            var countZ = 0;
            if (maxX - minX > config.ratio) {
                if (((minX - config.pickStartX) % config.ratio) != 0) {
                    countX = 1 + Math.ceil(((maxX - minX) - (config.ratio - (minX - config.pickStartX) % config.ratio)) / config.ratio);
                } else {
                    countX = Math.ceil((maxX - minX) / config.ratio);
                }
            }
            else {
                if (((minX - config.pickStartX) % config.ratio) != 0) {
                    if (((minX - config.pickStartX) % config.ratio) + (maxX - minX) > config.ratio) {
                        countX = 2
                    } else {
                        countX = 1;
                    }
                } else {
                    countX = 1;
                }
            }
            if (maxY - minY > config.ratio) {
                if (((minY - config.pickStartY) % config.ratio) != 0) {
                    countY = 1 + Math.ceil(((maxY - minY) - (config.ratio - (minY - config.pickStartY) % config.ratio)) / config.ratio);
                } else {
                    countY = Math.ceil((maxY - minY) / config.ratio);
                }
            } else {
                if (((minY - config.pickStartY) % config.ratio) != 0) {
                    if (((minY - config.pickStartY) % config.ratio) + (maxY - minY) > config.ratio) {
                        countY = 2;
                    } else {
                        countY = 1;
                    }
                }
                else {
                    countY = 1;
                }
            }
            if (maxZ - minZ > config.ratio) {
                if (((minZ - config.pickStartZ) % config.ratio) != 0) {
                    countZ = 1 + Math.ceil(((maxZ - minZ) - (config.ratio - (minZ - config.pickStartZ) % config.ratio)) / config.ratio);
                } else {
                    countZ = Math.ceil((maxZ - minZ) / config.ratio);
                }
            } else {
                if (((minZ - config.pickStartZ) % config.ratio) != 0) {
                    if (((minZ - config.pickStartZ) % config.ratio) + (maxZ - minZ) > config.ratio) {
                        countZ = 2;
                    } else {
                        countZ = 1;
                    }
                } else {
                    countZ = 1;
                }
            }
            // if(parseInt((maxX-minX)/config.ratio)==0){
            //     console.log("==0")
            // }
            // if(parseInt(((maxY-minY)/config.ratio))==0){
            //     console.log("==0")
            // }
            // if(parseInt(((maxZ-minZ)/config.ratio))==0){
            //     console.log("==0")
            // }
            // if((minX - config.pickStartX)%config.ratio+(maxX-minX)%config.ratio<=config.ratio){
            //     countX = parseInt(((maxX-minX)/config.ratio))+1;
            // }else{
            //     countX = parseInt(((maxX-minX)/config.ratio))+2;
            // }
            // if((minY - config.pickStartY)%config.ratio+(maxY-minY)%config.ratio<=config.ratio){
            //     countY = parseInt(((maxY-minY)/config.ratio))+1;
            // }else{
            //     countY = parseInt(((maxY-minY)/config.ratio))+2;
            // }
            // if((minZ - config.pickStartZ)%config.ratio+(maxZ-minZ)%config.ratio<=config.ratio){
            //     countZ = parseInt(((maxZ-minZ)/config.ratio))+1;
            // }else{
            //     countZ= parseInt(((maxZ-minZ)/config.ratio))+2;
            // }
            // console.log("--------------------------------")
            // console.log(minX)
            // console.log(offsetX)
            // console.log((minX - config.pickStartX) - offsetX*config.ratio)
            // var offsetY = Math.floor((minY - config.pickStartY)/config.ratio);
            // var offsetZ = Math.floor((minZ - config.pickStartZ)/config.ratio);
            // var countY = Math.ceil((maxY-minY)/config.ratio);
            // var countZ = Math.ceil((maxZ-minZ)/config.ratio);
            // console.log((minX - config.pickStartX)/config.ratio)
            // console.log((minY - config.pickStartY)/config.ratio)
            // console.log((minZ - config.pickStartZ)/config.ratio)
            // console.log(offsetX)
            // console.log(offsetY)
            // console.log(offsetZ)
            // console.log(countX)
            // console.log(countY)
            // console.log(countZ)
            // console.log(countX+"=="+countY+"=="+countZ)
            for (var z = 0; z < countZ; z++) {
                for (var y = 0; y < countY; y++) {
                    for (var x = 0; x < countX; x++) {
                        var tempPoint = [];
                        tempPoint.push(parseInt((minX - config.pickStartX) / config.ratio) + x);
                        tempPoint.push(parseInt((minY - config.pickStartY) / config.ratio) + y);
                        tempPoint.push((parseInt((minZ - config.pickStartZ) / config.ratio) + z));
                        Lighting.checkIsInner(tempPoint, config, scene);
                    }
                }
            }
        },
        checkIsInner: function (Point3, config, scene) {
            var flag1 = false;//在这一侧。。。
            var flag2 = false;//在另外一侧。。。
            if (config.a * (Point3[0]) + config.b * Point3[1] + config.c * Point3[2] + config.d > 0) {
                flag1 = true;
            } else if (config.a * Point3[0] + config.b * Point3[1] + config.c * Point3[2] + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0] + config.ratio) + config.b * Point3[1] + config.c * Point3[2] + config.d > 0) {
                flag1 = true;
            } else if (config.a * (Point3[0] + config.ratio) + config.b * Point3[1] + config.c * Point3[2] + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0] + config.ratio) + config.b * (Point3[1] + config.ratio) + config.c * Point3[2] + config.d > 0) {
                flag1 = true;
            } else if (config.a * (Point3[0] + config.ratio) + config.b * (Point3[1] + config.ratio) + config.c * Point3[2] + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0]) + config.b * (Point3[1] + config.ratio) + config.c * Point3[2] + config.d > 0) {
                flag1 = true;
            } else if (config.a * (Point3[0]) + config.b * (Point3[1] + config.ratio) + config.c * Point3[2] + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0]) + config.b * Point3[1] + config.c * (Point3[2] + config.ratio) + config.d > 0) {
                flag1 = true;
            } else if (config.a * Point3[0] + config.b * Point3[1] + config.c * (Point3[2] + config.ratio) + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0] + config.ratio) + config.b * Point3[1] + config.c * (Point3[2] + config.ratio) + config.d > 0) {
                flag1 = true;
            } else if (config.a * (Point3[0] + config.ratio) + config.b * Point3[1] + config.c * (Point3[2] + config.ratio) + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0] + config.ratio) + config.b * (Point3[1] + config.ratio) + config.c * (Point3[2] + config.ratio) + config.d > 0) {
                flag1 = true;
            } else if (config.a * (Point3[0] + config.ratio) + config.b * (Point3[1] + config.ratio) + config.c * (Point3[2] + config.ratio) + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }
            if (config.a * (Point3[0]) + config.b * (Point3[1] + config.ratio) + config.c * (Point3[2] + config.ratio) + config.d > 0) {
                flag1 = true;
            } else if (config.a * (Point3[0]) + config.b * (Point3[1] + config.ratio) + config.c * (Point3[2] + config.ratio) + config.d < 0) {
                flag2 = true;
            } else {
                console.log("==0");
            }

            if (!flag1 && flag2 || flag1 && !flag2) {
                Lighting.drawPoint({
                    ctx: secondCanvas.getContext("2d"),
                    x: Point3[0],
                    y: Point3[1],
                    z: Point3[2],
                    rh: config.pickHeight / config.ratio,
                    w: config.pickLength / config.ratio
                });
                // if(config.allSectionData[Point3[0]][Point3[1]][Point3[2]]!=1){
                //     config.allSectionData[Point3[0]][Point3[1]][Point3[2]]=1;
                //     var sm = new BABYLON.StandardMaterial("s", scene);
                //     sm.diffuseColor = new BABYLON.Color3(Math.random(), Math.random(), Math.random())
                //     var box = new BABYLON.Mesh.CreateBox("a", 1, scene);
                //     box.position.x = Point3[0];
                //     box.position.y = Point3[1];
                //     box.position.z = Point3[2];
                //     box.material = sm;
                // }
            }
            // else{
                // console.log("Func:ChickIsInner")
            // }
        },
        drawPoint: function (options) {
            options.ctx.fillStyle = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
            options.ctx.fillRect((options.x + (options.z * options.w)), options.rh - options.y, 1, 1);
        },
        CalculatePlaneEquation: function (vertex3Array, config) {
            var p1 = vertex3Array[0];
            var p2 = vertex3Array[1];
            var p3 = vertex3Array[2];
            config.a = ( (p2.y - p1.y) * (p3.z - p1.z) - (p2.z - p1.z) * (p3.y - p1.y) );
            config.b = ( (p2.z - p1.z) * (p3.x - p1.x) - (p2.x - p1.x) * (p3.z - p1.z) );
            config.c = ( (p2.x - p1.x) * (p3.y - p1.y) - (p2.y - p1.y) * (p3.x - p1.x) );
            config.d = ( 0 - (config.a * p1.x + config.b * p1.y + config.c * p1.z) );
            return true;
        },
        FillInner: function (tempArray, scene) {
            Lighting.wrapOriginSectionArray(tempArray, scene);
        },
        wrapOriginSectionArray: function (tempArray, scene) {
            var tempWrapArray = [];
            var tempXArray = [];//tempX数据、
            var tempYArray = [];//tempY数据、
            //初始化+2数组
            for (var i = 1; i < ((tempArray[0].length + 2) * (tempArray[0][0].length + 2) * tempArray.length) + 1; i++) {
                tempXArray.push(0);
                if (i % (tempArray[0][0].length + 2) == 0) {
                    tempYArray.push(tempXArray);
                    tempXArray = [];
                }
                if (i % ((tempArray[0].length + 2) * (tempArray[0][0].length + 2)) == 0) {
                    tempWrapArray.push(tempYArray);
                    tempYArray = [];
                }
            }
            var temp2array = [].concat(tempWrapArray);

            var box;
            //+2赋值
            for (var i = 0; i < tempArray.length; i++) {
                for (var j = 0; j < tempArray[0].length; j++) {
                    for (var k = 0; k < tempArray[0][0].length; k++) {
                        if (tempArray[i][j][k] != 0) {
                            temp2array[i][j + 1][k + 1] = 1;
                        }
                    }
                }
                var startX = 0;
                var startY = 0;
                // 递归四联通取反
                Lighting.fourUnion(temp2array[i], startX, startY);
            }
            Lighting.unWrapOriginSectionArray(temp2array, tempArray);
        },
        fourUnion: function (temparray, startX, startY) {
            temparray[startY][startX] = 4;
            if (startY > 0 && temparray[startY - 1][startX] == 0) {
                Lighting.fourUnion(temparray, startX, startY - 1)
            }
            if (startX < (temparray[0].length - 1) && temparray[startY][startX + 1] == 0) {
                Lighting.fourUnion(temparray, startX + 1, startY)
            }
            if (startY < (temparray.length - 1) && temparray[startY + 1][startX] == 0) {
                Lighting.fourUnion(temparray, startX, startY + 1)
            }
            if (startX > 0 && temparray[startY][startX - 1] == 0) {
                Lighting.fourUnion(temparray, startX - 1, startY)
            }
        },
        /*
         temp2Array:包围的数组
         tempArray:原始数组
         */
        unWrapOriginSectionArray: function (temp2array, tempArray) {
            for (var tz = 0; tz < tempArray.length; tz++) {
                for (var ty = 0; ty < tempArray[0].length; ty++) {
                    for (var tx = 0; tx < tempArray[0][0].length; tx++) {
                        tempArray[tz][ty][tx] = temp2array[tz][ty + 1][tx + 1];
                    }
                }
            }
        },
        consoleSectionData: function (config) {
            console.log(config.allSectionData)
        },
        drawGap: function (config, scene) {
            var ctx = secondCanvas.getContext("2d");
            for (var i = 0; i < config.meshWidth; i++) {
                ctx.moveTo(i * config.meshLength, 0);
                ctx.lineTo(i * config.meshLength, config.meshHeight);
                // ctx.lineTo(secondCanvas.width, secondCanvas.height)
                // ctx.lineTo(0, secondCanvas.height)
            }
            ctx.stroke();
        },
        draw2dSection: function (config, scene, data) {
            var tempArray = data;
            material = new BABYLON.StandardMaterial("texture1", scene);
            material.backFaceCulling = false;
            material.alpha = 1;
            material.diffuseTexture = new BABYLON.DynamicTexture("dynamic", secondCanvas, scene, true);
            // secondCanvas.width = secondCanvas.width;
            var ctx = secondCanvas.getContext("2d");
            ctx.clearRect(0, 0, secondCanvas.width, secondCanvas.height);
            for (var i = 0; i < tempArray.length; i++) {
                for (var j = 0; j < tempArray[0].length; j++) {
                    for (var k = 0; k < tempArray[0][0].length; k++) {
                        if (config.isInnerFill) {
                            if (tempArray[i][j][k] != 4) {
                                ctx.fillStyle = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
                                Lighting.draw2dData(k, (tempArray[0].length - j), i, tempArray[0][0].length, ctx);
                            }
                        } else {
                            if (tempArray[i][j][k] == 1) {
                                ctx.fillStyle = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
                                Lighting.draw2dData(k, (tempArray[0].length - j), i, tempArray[0][0].length, ctx);
                            }
                        }

                    }
                }
            }
        },
        draw2dData: function (x, y, z, w, ctx) {
            var r = 1;
            ctx.fillRect((x + (z * w)) * r, y * r, r, r);
        },
        drawFireworkData: function (x, y, z, h, w, ctx,color) {
            var r = 1;
            if (x < 0 || y < 0 || z < 0)return;
            (color)?ctx.fillStyle = 'rgba('+Math.round(color.r*255)+','+Math.round(color.g*255)+','+Math.round(color.b*255)+','+color.a+')':ctx.fillStyle = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
            // ctx.fillStyle = '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
            ctx.fillRect((x + (z * w)) * r, h - y * r, r, r);
        },
        getRandomBetween: function (Min, Max) {
            var Range = Max - Min;
            var Rand = Math.random();
            var num = Min + Math.round(Rand * Range); //四舍五入
            return num;
        },
        getRandomString: function (len) {
            len = len || 32;
            var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
            /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
            var maxPos = $chars.length;
            var pwd = '';
            for (i = 0; i < len; i++) {
                pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
            }
            return pwd;
        },
        extendJqueryLoadJsFunc: function () {
            if (!$) {
                console.log("404:Jquery not found!");
                return;
            }
            $.cachedScript = function (url, options) {
                for (var s in scriptsArray) {
                    if (scriptsArray[s] == url) {
                        return {
                            done: function (method) {
                                if (typeof method == 'function') {
                                    method();
                                }
                            }
                        };
                    }
                }
                options = $.extend(options || {}, {
                    dataType: "script",
                    url: url,
                    cache: true
                });
                scriptsArray.push(url); //将url地址放入script标记数组中
                return $.ajax(options);
            };
        },
        showAxis: function (size, scene) {
            var makeTextPlane = function (text, color, size, position) {
                var plane = new BABYLON.Mesh.CreatePlane("TextPlane", size, scene, true);
                if (false) {
                    // Attempt to use Canvas2D
                    // Compilation error: "Line 8:18899 - i.clone is not a function"
                    planeWs2d = new BABYLON.WorldSpaceCanvas2D(scene, size, {
                        id: text,
                        worldPosition: position,
                        backgroudFill: "#C0C0C040",
                        children: [
                            new BABYLON.Text2D(text, {
                                fontName: "bold 36px Arial",
                                marginAlignment: "h: center, v: bottom"
                            })
                        ]
                    });
                } else {
                    var dynamicTexture =
                        new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true);
                    dynamicTexture.hasAlpha = true;
                    dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color,
                        "transparent", true);
                    plane.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL;
                    plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene);
                    plane.material.backFaceCulling = false;
                    plane.material.specularColor = new BABYLON.Color3(0, 0, 0);
                    plane.material.diffuseTexture = dynamicTexture;
                    plane.position = position;
                }
                return plane;
            };
            var ticks = function (axis, size) {
                var axis_ticks = [];
                var short_tick_len = 1.0 / 4;
                var long_tick_len = 1.0 / 2;
                switch (axis) {
                    case "x":
                        // Short ticks
                        for (x = 0.5; x < size; x += 1.0) {
                            line = [
                                new BABYLON.Vector3(x, short_tick_len / 2, 0),
                                new BABYLON.Vector3(x, 0, 0),
                                new BABYLON.Vector3(x, 0, 0),
                                new BABYLON.Vector3(x, 0, short_tick_len / 2)
                            ];
                            axis_ticks.push(line);
                        }
                        // Long ticks
                        tick_len = 1.0 / 4;
                        for (x = 1; x < size; x += 1.0) {
                            line = [
                                new BABYLON.Vector3(x, long_tick_len / 2, 0),
                                new BABYLON.Vector3(x, 0, 0),
                                new BABYLON.Vector3(x, 0, 0),
                                new BABYLON.Vector3(x, 0, long_tick_len / 2)
                            ];
                            axis_ticks.push(line);
                        }
                        break;
                    case "y":
                        // Short ticks
                        tick_len = 1.0 / 4;
                        for (y = 0.5; y < size; y += 1.0) {
                            line = [
                                new BABYLON.Vector3(0, y, short_tick_len / 2),
                                new BABYLON.Vector3(0, y, 0),
                                new BABYLON.Vector3(0, y, 0),
                                new BABYLON.Vector3(short_tick_len / 2, y, 0)
                            ];
                            axis_ticks.push(line);
                        }
                        // Long ticks
                        tick_len = 1.0 / 2;
                        for (y = 1; y < size; y += 1.0) {
                            line = [
                                new BABYLON.Vector3(0, y, long_tick_len / 2),
                                new BABYLON.Vector3(0, y, 0),
                                new BABYLON.Vector3(0, y, 0),
                                new BABYLON.Vector3(long_tick_len / 2, y, 0)
                            ];
                            axis_ticks.push(line);
                        }
                        break;
                    case "z":
                        tick_len = 1.0 / 4;
                        for (z = 0.5; z < size; z += 1.0) {
                            line = [
                                new BABYLON.Vector3(0, short_tick_len / 2, z),
                                new BABYLON.Vector3(0, 0, z),
                                new BABYLON.Vector3(0, 0, z),
                                new BABYLON.Vector3(short_tick_len / 2, 0, z)
                            ];
                            axis_ticks.push(line);
                        }
                        // Long ticks
                        tick_len = 1.0 / 2;
                        for (z = 1; z < size; z += 1.0) {
                            line = [
                                new BABYLON.Vector3(0, long_tick_len / 2, z),
                                new BABYLON.Vector3(0, 0, z),
                                new BABYLON.Vector3(0, 0, z),
                                new BABYLON.Vector3(long_tick_len / 2, 0, z)
                            ];
                            axis_ticks.push(line);
                        }
                        break;
                }
                return axis_ticks;
            };
            var axisX_line = [
                [new BABYLON.Vector3.Zero(),
                    new BABYLON.Vector3(size, 0, 0),],
                [new BABYLON.Vector3(size * 0.95, 0.05 * size, 0),
                    new BABYLON.Vector3(size, 0, 0),],
                [new BABYLON.Vector3(size, 0, 0),
                    new BABYLON.Vector3(size * 0.95, -0.05 * size, 0),],
            ];
            var axisX = BABYLON.MeshBuilder.CreateLineSystem(
                "axisX", {lines: axisX_line}, scene);
            axisX.color = new BABYLON.Color3(1, 0, 0);
            var axisX_ticks = BABYLON.MeshBuilder.CreateLineSystem(
                "axisX_ticks",
                {lines: ticks("x", size)},
                scene);
            axisX_ticks.color = axisX.color;
            var position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0);
            var xChar = makeTextPlane("X", "red", size / 10, position);
            var axisy_line = [
                [new BABYLON.Vector3.Zero(),
                    new BABYLON.Vector3(0, size, 0),],
                [new BABYLON.Vector3(0, size, 0),
                    new BABYLON.Vector3(0.05 * size, size * 0.95, 0)],
                [new BABYLON.Vector3(0, size, 0),
                    new BABYLON.Vector3(-0.05 * size, size * 0.95, 0)],
            ];
            var axisY = BABYLON.MeshBuilder.CreateLineSystem(
                "axisY", {lines: axisy_line}, scene);
            axisY.color = new BABYLON.Color3(0, 1, 0);
            var axisY_ticks = BABYLON.MeshBuilder.CreateLineSystem(
                "axisY_ticks", {lines: ticks("y", size)}, scene);
            axisY_ticks.color = axisY.color;
            var position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size);
            var yChar = makeTextPlane("Y", "green", size / 10, position);
            var axisZ_line = [
                [new BABYLON.Vector3.Zero(),
                    new BABYLON.Vector3(0, 0, size),],
                [new BABYLON.Vector3(0, 0, size),
                    new BABYLON.Vector3(0, 0.05 * size, size * 0.95)],
                [new BABYLON.Vector3(0, 0, size),
                    new BABYLON.Vector3(0, -0.05 * size, size * 0.95)],
            ];
            var axisZ = BABYLON.MeshBuilder.CreateLineSystem(
                "axisZ", {lines: axisZ_line}, scene);
            axisZ.color = new BABYLON.Color3(0, 0, 1);
            var axisZ_ticks = BABYLON.MeshBuilder.CreateLineSystem(
                "axisZ_ticks", {lines: ticks("z", size)}, scene);
            axisZ_ticks.color = axisZ.color;
            var position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size);
            var zChar = makeTextPlane("Z", "blue", size / 10, position);
        },
        deepCopy: function (o) {
            if (o instanceof Array) {
                var n = [];
                for (var i = 0; i < o.length; ++i) {
                    n[i] = Lighting.deepCopy(o[i]);
                }
                return n;

            } else if (o instanceof Object) {
                var n = {};
                for (var i in o) {
                    n[i] = Lighting.deepCopy(o[i]);
                }
                return n;
            } else {
                return o;
            }
        },
        extend: function (a, b) {
            for (var i in b) {
                a[i] = b[i];
            }
        }
    };
    return Lighting;
}));
var DRAG = (function () {
    var drag = function (elementId, $rootScope) {
        var isDown = false;
        var ObjLeft, ObjTop, posX, posY, obj, offsetX, offsetY;
        /*按下鼠标左键*/
        function down(event) {
            obj.style.cursor = "move";
            isDown = true;
            if (isDown == true) {
                ObjLeft = obj.offsetLeft;
                ObjTop = obj.offsetTop;
                posX = parseInt(mousePosition(event).x);
                posY = parseInt(mousePosition(event).y);
                offsetX = posX - ObjLeft;
                offsetY = posY - ObjTop;
            }
        }
        /*移动中*/
        function move(event, $rootScope) {
            if (isDown == true) {
                obj.style.cursor = "move";
                var x = mousePosition(event).x - offsetX;
                var y = mousePosition(event).y - offsetY;
                var w = document.documentElement.clientWidth - obj.offsetWidth;
                var h = document.documentElement.clientHeight - obj.offsetHeight;
                x = Math.min(w, Math.max(0, x));
                y = Math.min(h, Math.max(0, y));
                obj.style.left = x + 'px';
                obj.style.top = y + 'px';
                var appElement = document.querySelector('[ng-controller=MenuCtrl]');
                // var $scope = angular.element(appElement).scope();
                // $scope.sectionContentOffsetX = x;
                // $scope.sectionContentOffsetY = y;
                // $scope.$apply();
            }
        }
        /*松开鼠标左键*/
        function up($rootScope) {
            isDown = false;
            obj.style.cursor = "default";

        }
        /*获取鼠标坐标*/
        function mousePosition(evt) {
            var xPos, yPos;
            evt = evt || window.event;
            if (evt.pageX) {
                xPos = evt.pageX;
                yPos = evt.pageY;
            } else {
                xPos = evt.clientX + document.body.scrollLeft - document.body.clientLeft;
                yPos = evt.clientY + document.body.scrollTop - document.body.clientTop;
            }
            return {
                x: xPos,
                y: yPos
            }
        }
        obj = document.getElementById(elementId);
        obj.onmousedown = down;
        document.onmouseup = up;
        document.onmousemove = move;
    }
    return {
        drag: drag,
    };
})();